#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# This file is part of KeyExtracta
# <http://code.google.com/p/keyextracta/>.
#
# KeyExtracta is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# KeyExtracta is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with KeyExtracta.  If not, see <http://www.gnu.org/licenses/>.

# This script is meant to automate the building of the distribution packages
# All packages stored in the dist directory.
# Currently this script performs the following operations:
#   1.  Build source tarball using distutils.
#   2.  Build binary files using cx_freeze.
#   3.  Compress binary files using UPX.
#   4.  Build binary file archive package.
#   5.  Build binary installer file using NSIS.

import subprocess, os, shutil

# Directories
upxPath = 'I:\PortableApps\FreeUPXPortable\App\FreeUPX'
nsisPath = 'I:\PortableApps\NSISPortable\App\NSIS'
binBuildPath = 'build\exe.win32-2.7'

appName = 'KeyExtracta'
version = '0.1.1'
binDir = '%s-%s' % (appName, version)
zipFileName = '%s.zip' % binDir
distFileName = '%s-setup.exe' % binDir.lower()
distScriptName = '%s-build-setup.nsi' % appName.lower()
upxExe = 'upx.exe'
upxCompType = '--ultra-brute' # --all-methods, --brute, --ultra-brute
nsisExe = 'makensis.exe'

def getDriveLetter():
  """Get current drive letter"""
  drive, path = os.path.splitdrive(os.getcwd())
  return drive
  
def cleanPath(l):
  """Clean up path  from list"""
  drive = getDriveLetter()
  pl = []
  for s in l:
    # Try to make it portable if given path does not exist
    if not os.path.exists(s):
      # s = ''
      oldDrive, path = os.path.splitdrive(s)
      path = path.lstrip(os.sep)
      cwd = os.getcwd()
      if os.path.exists(os.path.join(cwd, path)):
        s = os.path.join(cwd, path)
      elif os.path.exists(os.path.join(drive, os.sep, path)):
        s = os.path.join(drive, os.sep, path)
    if s and not s in os.environ["PATH"]:
      pl.append(s)
  return pl   

def makePathList():
  """Make the PATH list from made variables"""
  return [upxPath, nsisPath]

def setPath():
  """Set PATH environmental variable from list"""
  l = makePathList()
  l = cleanPath(l)
  os.environ["PATH"] += os.pathsep + os.pathsep.join(l)

def cleanup():
  """Cleanup from previous build"""
  dirName = os.path.dirname(binBuildPath)
  if os.path.isdir(os.path.join(dirName, binDir)):
     shutil.rmtree(os.path.join(dirName,binDir))
  
def buildSourceDist():
  """Build source distribution"""
  subprocess.call(['python', 'setup.py', 'sdist'], shell=True)

def buildBin():
  """Build binary files"""
  subprocess.call(['python', 'setup.py', 'build'], shell=True)

def compressBinFiles():
  """Compress binary files using UPX"""
  dirList = os.listdir(binBuildPath)
  for file in dirList:
    f = os.path.join(binBuildPath, file)
    if os.path.isfile(f):
      subprocess.call([upxExe, upxCompType, f], shell=True)

def buildBinArchive():
  """Build binary archive file"""
  dirName = os.path.dirname(binBuildPath)
  if os.path.isdir(binBuildPath):
    os.rename(binBuildPath, os.path.join(dirName,binDir))
    print 'Creating zip archive'
    shutil.make_archive(binDir, format="zip", root_dir=dirName)
    if os.path.isfile(zipFileName):
      shutil.move(zipFileName, 'dist')

def buildBinDist():
  """Build binary distribution file"""
  if os.path.isfile(distScriptName):
    print 'Creating binary installer'
    subprocess.call([nsisExe, distScriptName], shell=True)
    if os.path.isfile(distFileName):
      shutil.move(distFileName, 'dist')
    else:
      print '%s does not exist' % distFileName
  else:
    print '%s does not exist' % distScriptName 
  
setPath()
cleanup()
buildSourceDist()
buildBin()
compressBinFiles()
buildBinArchive()
buildBinDist()
